package com.ucode.hrm.handle;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.fadada.sdk.base.client.FddBaseClient;
import com.fadada.sdk.base.model.req.*;
import com.fadada.sdk.extra.client.FddExtraClient;
import com.fadada.sdk.extra.model.req.AddKeysParams;
import com.fadada.sdk.extra.model.req.DocusignAcrossPageParams;
import com.fadada.sdk.extra.model.req.GetPdfTemplateKeysParams;
import com.fadada.sdk.extra.model.req.PersonVerifySignParams;
import com.ucode.model.hrm.enums.HrmSysResultCodeEnum;
import com.ucode.model.hrm.vo.HrmGenerateContractParams;
import com.ucode.tool.exception.UcodeServiceException;
import com.ucode.tool.util.JsonUtils;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * 法大大 API 接口处理类
 *
 * 注意：我们这里统一用PDF模板（可以自定义参数名称），不使用在线模板（无法自定义参数名称）
 * @Author: liliang
 * @Date: 2025/6/6 21:30
 * @Version: 1.0
 */
@Service
public class FddAPIHandler {

    private static Log log = LogFactory.get();

    private String APPID = "501177";
    private String APPKEY = "7CaBgcxwQbWJ6QwCrhYGHMFw";
    private String V = "2.0";
    //private String HOST = "https://textapi.fadada.com/api2/"; //正式环境
    private String HOST = "https://textapi12.fadada.com/api2/";

    public static String customerId = "526DC65317DE53155A75D9F4BD736680";


    //测试环境
    //private String APPID = "405118";
    //private String APPKEY = "qoftM6bDSQsKwAOc9pLWItmp";
    //private String V = "2.0";
    //private String HOST = "https://testapi.fadada.com:8443/api/" ;//测试环境
    //public static String customerId = "DDA3C59E475B3882017CB79A6ABFA0FB";

    //签署结果异步通知URL
    private String signNotifyUrl="http://wap.shengshirencai.com/api-wap/hrm/employee-contract/sign-notify";

    private String authNotifyUrl="http://sswap.shengshirencai.com/api-wap/hrm/employee-contract/auth-notify";


    /**
     * 注册账号
     * @param accountType 账号类型 1个人 2企业
     * @param openId 平台方自定义唯一标识
     * @return 返回法大大的customer_id 后续签署合同会用到
     */
    public String registerAccount(String accountType,String openId){
        FddBaseClient baseClient = new FddBaseClient(APPID, APPKEY, V, HOST);
        RegisterAccountParams params = new RegisterAccountParams();
        params.setAccountType(accountType); //账号类型1个人 2企业
        params.setOpenId(openId); //平台方自定义唯一标识

        String result = baseClient.invokeRegisterAccount(params);

        log.info("法大大API接口调用,注册账号返回值:{}",result);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if("1".equals(jsonObject.getStr("code")) && ObjUtil.isNotNull(jsonObject.getStr("data"))){
            return jsonObject.getStr("data");
        }
        throw new UcodeServiceException(HrmSysResultCodeEnum.FADADA_API_REQUEST_ERROR,"注册账号",jsonObject.get("msg"));
    }
    /**
     * 添加电子印章
     * @param imgUrl
     * @return
     */
    public String addSignature(String imgUrl){
        FddBaseClient baseClient = new FddBaseClient(APPID, APPKEY, V, HOST);
        AddSignatureParams params = new AddSignatureParams();
        params.setCustomerId(customerId); //客户编号
        //下面章图片base64、签章图片、图片公网地址三选一
        //params.setSignatureImgBase64(""); //签章图片base64
        //params.setFile(new File("D:\\sign.png")); //签章图片
        params.setImgUrl(imgUrl); //签章图片公网地址
        String result = baseClient.invokeAddSignature(params);
        log.info("法大大API接口调用,添加印章返回值:{}",result);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if("1".equals(jsonObject.getStr("code")) && ObjUtil.isNotNull(jsonObject.getJSONObject("data"))){
            //处理成功
            String signatureId = jsonObject.getJSONObject("data").getStr("signature_id");
            return signatureId;
        }

        throw new UcodeServiceException(HrmSysResultCodeEnum.ADD_SIGNATURE_ERROR,jsonObject.get("msg"));
    }

    /***
     * 添加表单域到模板
     * 在线模板调用模板填充接口前调用
     * @param templateId
     * @return
     */
    public String addContractByTplKeys(String templateId){
        FddExtraClient client = new FddExtraClient(APPID, APPKEY, V, HOST);
        AddKeysParams params = new AddKeysParams();
        params.setContractTemplateId(templateId);
        String result = client.invokeAddKeys(params);

        log.info("法大大API接口调用,添加表单域到模板返回值:{},请求参数:{}",result,templateId);

        GetPdfTemplateKeysParams params2 = new GetPdfTemplateKeysParams();
        params2.setTemplateId(templateId);
        params2.setFillType(0);//模板类型 0-pdf模板，1-在线模板【重点注意：要使用pdf模板，看顶部类说明】
        String result2 = client.invokeGetPdfTemplateKeys(params2);
        log.info("法大大API接口调用,获取到模板中可填充的key-value键值对返回值:{},请求参数:{}",result2,templateId);
        return result;
    }

    /**
     * 获取 pdf 模版表单域 key 值
     * @param templateId
     * @return
     */
    public List<String> getTemplateKeys(String templateId){
        FddExtraClient client = new FddExtraClient(APPID, APPKEY, V, HOST);
        GetPdfTemplateKeysParams params = new GetPdfTemplateKeysParams();
        params.setTemplateId(templateId);
        params.setFillType(0);//模板类型 0-pdf模板，1-在线模板
        String result = client.invokeGetPdfTemplateKeys(params);
        log.info("法大大API接口调用,获取 pdf 模版表单域 key 值返回值:{}",result);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if("1".equals(jsonObject.getStr("code")) && ObjUtil.isNotNull(jsonObject.getJSONArray("data"))){
            //处理成功
            return JSONUtil.toList(jsonObject.getStr("data"), String.class);
        }

        throw new UcodeServiceException(HrmSysResultCodeEnum.FADADA_API_REQUEST_ERROR,"获取 pdf 模版表单域 key 值",result);
    }

    /**
     *  模板填充方式生成合同
     *  将需填充的内容通过模板填充接口传入，即可生成合同供签署操作
     * @param templateId
     * @param docTitle
     * @param contractId
     * @param paramsMap
     * @return
     */
    public Map<String,String> generateContractByTpl(String templateId, String docTitle, String contractId, HrmGenerateContractParams paramsMap){
        FddBaseClient baseClient = new FddBaseClient(APPID, APPKEY, V, HOST);
        GenerateContractParams params = new GenerateContractParams();
        params.setTemplateId(templateId);  //模板编号
        params.setContractId(contractId); //合同编号
        //以下是非必填参数
        params.setDocTitle(docTitle); // 文档标题
        params.setFontSize("12"); //字体大小
        params.setFontType(""); //字体类型
        params.setFillType("0");// 0 pdf 模板、1 在线填充模板 【重点注意：要使用pdf模板，看顶部类说明】
        params.setParameterMap(JsonUtils.toJsonString(paramsMap)); //填充内容,json字符串
        //params.setDynamicTables(getdynamic_tables()); //动态表格
        //// 在版本号设置为 2.1 时，实现了对填充内容和动态表单进行3DES加密
        //baseClient.setVersion("2.1");
        String result = baseClient.invokeGenerateContract(params);

        log.info("法大大API接口调用,通过模板填充方式生成合同返回值:{},请求参数:{}",result,JsonUtils.toJsonString(params));

        Map<String,String> resultData = JsonUtils.parseObject(result, Map.class);
        if("1000".equals(resultData.get("code")) && "success".equals(resultData.get("result"))){
            //处理成功
            String download_url = resultData.get("download_url");//合同下载地址
            String viewpdf_url = resultData.get("viewpdf_url");//合同预览地址
            Map<String,String> resultMap = new HashMap<>();
            resultMap.put("download_url",urlConversionByProd(download_url));
            resultMap.put("viewpdf_url",urlConversionByProd(viewpdf_url));
            return resultMap;
        }
        throw new UcodeServiceException(HrmSysResultCodeEnum.CONTRACT_GENERATE_ERROR);
    }

    /**
     * 快捷签署（个人），该接口是签署、实名认证一体的
     * @param transactionId 交易号,必填,请以US开头
     * @param contractId
     * @param customerId
     * @param signKeyword
     * @param keywordStrategy
     * @return 返回的签署地址，24小时有效，申请后7天有效
     */
    public String personVerifySign(String transactionId,String contractId, String customerId, String signKeyword,String keywordStrategy){
        FddExtraClient client = new FddExtraClient(APPID, APPKEY, V, HOST);
        PersonVerifySignParams params = new PersonVerifySignParams();
        params.setTransactionId(transactionId);//接入方自定义交易号
        params.setContractId(contractId);//待签署合同编号
        params.setCustomerId(customerId);//接入方获取的客户编号【注意：这里是签署方的，不是甲方的】
        params.setReturnUrl("pages/hrm/my/contractList");//签署结果同步回调地址，当签章完成后，在签章页面停留数秒后浏览器会自动跳转到此URL，内容由接入平台自行展示；参见页面跳转规范（return_url)注：支持传入微信和支付宝小程序path小程序path格式如下：pages/index/index.
        params.setNotifyUrl(signNotifyUrl);//签署结果异步回调地址
        params.setPageModify("1");//1允许修改 2不允许修改
        params.setVerifiedNotifyUrl(authNotifyUrl);//认证结果异步回调地址
        params.setVerifiedWay("1");//实名认证套餐类型
        //以下参数为选填
        params.setSignKeyword(signKeyword); //盖章定位关键字
        params.setKeywordStrategy(keywordStrategy); //0-所有关键字签章 （默认） 1-第一个关键字签章 2-最后一个关键字签章
        params.setSignaturePositions("");
        params.setCustomerName("");
        params.setCustomerIdentType("");
        params.setCustomerIdentNo("");
        params.setCertType("");
        params.setMobile("");
        params.setAreaCode("");
        //params.setMobileSignType("2");//手动签章
        params.setMobileSignType("");
        params.setPersonAuthFailAllowManualAudit("");
        params.setBankCardNo("");
        params.setIdentFrontPath("");
        params.setIdentBackPath("");
        params.setIdPhotoOptional("");
        params.setSignatureShowTime("");
        params.setPcHandSignature("1");
        params.setIsMiniProgram("3");//
        String result = client.invokePersonVerifySign(params);

        log.info("法大大API接口调用,快捷签署（个人)返回值:{}",result);
        JSONObject jsonObject = JSONUtil.parseObj(result);
        if("1".equals(jsonObject.getStr("code")) && ObjUtil.isNotNull(jsonObject.getJSONObject("data"))){
            //处理成功
            String url = jsonObject.getJSONObject("data").getStr("url");
            return urlConversionByProd(Base64.decodeStr(url));
        }

        throw new UcodeServiceException(HrmSysResultCodeEnum.FADADA_API_REQUEST_ERROR,"快捷签（个人）",jsonObject.get("msg"));
    }

    /**
     * 自动签署（用于员工侧）,这个接口使用之前需要先进行实名认证
     * @param transactionId
     * @param docTitle
     * @param contractId
     * @param signKeyword
     * @param keywordStrategy
     * @return  一个签署链接,点开后，将跳转到合同签署页面，用户可进行签署操作（返回的签署地址没有有效期）
     */
    public String extSignContract(String transactionId, String docTitle, String contractId,String customerId, String signKeyword,String keywordStrategy){
        FddBaseClient client = new FddBaseClient(APPID, APPKEY, V, HOST);
        ExtSignParams params = new ExtSignParams();
        params.setTransactionId(transactionId);//平台自定义唯一交易号
        params.setContractId(contractId);//此处传入调用上传或填充合同接口成功时定义的合同编号
        params.setCustomerId(customerId);//此处传入认证成功后成功绑定实名信息的客户编号
        params.setDocTitle(docTitle); //"如：租赁合同协议"
        params.setPositionType("0");//0-关键字（默认）1-坐标
        params.setSignKeyword(signKeyword);//盖章定位关键字
        params.setKeywordStrategy(keywordStrategy);//0-所有关键字签章 （默认） 1-第一个关键字签章 2-最后一个关键字签章
        params.setNotifyUrl(signNotifyUrl);
        String result = client.invokeExtSign(params);
        log.info("法大大API接口调用,手动自动签署返回值:{}",result);
        return result;
    }

    /**
     * 自动签署合同（用于公司侧）
     * 注意：请先调用“获取授权自动签页面接口-before_authsign.api”获取自动签权限！
     * @param transactionId 每次请求视为一个交易。只允许长度<=32的英文或数字字符。 交易号为接入平台生成，必须保证唯一并自行记录,请以CS开头
     * @param docTitle
     * @param contractId
     * @param signKeyword
     * @param keywordStrategy
     * @param signatureId
     * @return
     */
    public Map<String,String> extSignAutoContract(String transactionId, String docTitle, String contractId, String signKeyword,String keywordStrategy,String signatureId){
        FddBaseClient client = new FddBaseClient(APPID, APPKEY, V, HOST);
        ExtSignAutoParams params = new ExtSignAutoParams();
        params.setTransactionId(transactionId);//平台自定义唯一交易号
        params.setContractId(contractId);//此处传入调用上传或填充合同接口成功时定义的合同编号
        params.setCustomerId(customerId);//此处传入认证成功后成功绑定实名信息的客户编号
        params.setDocTitle(docTitle);
        params.setPositionType("0");//0-关键字（默认）1-坐标
        params.setSignKeyword(signKeyword);//盖章、签署定位关键字
        params.setKeywordStrategy(keywordStrategy);//0：所有关键字签章  1：第一个关键字签章 ；   2：最后一个关键字签章
        params.setSignatureId(signatureId);//选填，印章编号，调新增签章接口返回
        params.setNotifyUrl(signNotifyUrl);
        String result = client.invokeExtSignAuto(params);

        log.info("法大大API接口调用,合同自动签署返回值:{}",result);

        Map<String,String> resultData = JsonUtils.parseObject(result, Map.class);

        if("1000".equals(resultData.get("code")) && "success".equals(resultData.get("result"))){
            //处理成功
            String download_url = resultData.get("download_url");//合同下载地址
            String viewpdf_url = resultData.get("viewpdf_url");//合同预览地址
            Map<String,String> resultMap = new HashMap<>();
            resultMap.put("download_url",urlConversionByProd(download_url));
            resultMap.put("viewpdf_url",urlConversionByProd(viewpdf_url));
            return resultMap;
        }
        throw new UcodeServiceException(HrmSysResultCodeEnum.CONTRACT_GENERATE_ERROR);
    }

    /**
     * 骑缝章自动签
     * 请先调用“获取授权自动签页面接口-before_authsign.api”获取自动签权限，谢谢理解！且需盖骑缝章合同的页数必须大于1页,请以CS开头
     * @param transactionId
     * @param contractId
     * @param customerId
     * @param signatureId
     * @return
     */
    public Map<String,String> docusignAcrossPage(String transactionId,String contractId,String customerId,String signatureId){
        FddExtraClient client = new FddExtraClient(APPID, APPKEY, V, HOST);
        DocusignAcrossPageParams params = new DocusignAcrossPageParams();
        params.setTransactionId(transactionId);//自定义唯一交易号
        params.setContractId(contractId);
        params.setCustomerId(customerId);
        params.setAcrossSignatureId(signatureId);//自定义印章ID，非必填
        params.setNotifyUrl(signNotifyUrl);
        String result = client.invokeDocusignAcrossPage(params);
        log.info("法大大API接口调用,加盖骑缝章返回值:{},请求参数:{}",result,JsonUtils.toJsonString(params));

        Map<String,String> resultData = JsonUtils.parseObject(result, Map.class);
        if("1000".equals(resultData.get("code")) && "success".equals(resultData.get("result"))){
            //处理成功
            String download_url = resultData.get("download_url");//合同下载地址
            String viewpdf_url = resultData.get("viewpdf_url");//合同预览地址
            Map<String,String> resultMap = new HashMap<>();
            resultMap.put("download_url",urlConversionByProd(download_url));
            resultMap.put("viewpdf_url",urlConversionByProd(viewpdf_url));
            return resultMap;
        }else if("2002".equals(resultData.get("code")) && "合同只有一页，不允许骑缝章签署".equals(resultData.get("msg"))){
            return null;
        }
        throw new UcodeServiceException(HrmSysResultCodeEnum.CONTRACT_DOCUSIGN_ACROSS_ERROR);

    }

    /**
     * 获取授权自动签页面接口
     * @param transactionId 交易号,必填,请以AAS开头
     * @param contractId
     * @param customerId
     * @return
     */
    public String getAuthAutoSign(String transactionId,String contractId, String customerId){
        FddBaseClient client = new FddBaseClient(APPID, APPKEY, V, HOST);
        BeforeAuthSignParams params = new BeforeAuthSignParams();
        params.setTransactionId(transactionId);//平台自定义唯一交易号
        params.setAuthType("1");//1:授权自动签（目前只能填1）
        params.setContractId(contractId);//指该份线上授权委托书的合同编号，自定义即可
        params.setCustomerId(customerId);//传入注册返回的个人或企业客户编号
        params.setReturnUrl("");//同步通知签署结果地址
        params.setNotifyUrl(signNotifyUrl);//异步通知签署结果地址
        String result = client.invokeBeforeAuthSign(params);
        return urlConversionByProd(result);
    }

    /**
     * 查询授权自动签状态
     * @param customerId
     * @return
     */
    public Boolean getAuthAutoSignStatus(String customerId){
        FddBaseClient client = new FddBaseClient(APPID, APPKEY, V, HOST);
        GetAuthStatusParams params = new GetAuthStatusParams();
        params.setCustomerId(customerId);//传入调用授权自动签接口授权之后的客户编号
        String result = client.invokeGetAuthStatus(params);
        log.info("法大大API接口调用,查询授权自动签状态返回值:{},请求参数:{}",result,JsonUtils.toJsonString(params));

        JSONObject jsonObject = JSONUtil.parseObj(result);
        if("1".equals(jsonObject.getStr("code")) && ObjUtil.isNotNull(jsonObject.getJSONObject("data"))){
            //处理成功
            String status = jsonObject.getJSONObject("data").getStr("status");
            return "1".equals(status);
        }
        throw new UcodeServiceException(HrmSysResultCodeEnum.FADADA_API_REQUEST_ERROR,"查询授权自动签状态",result);
    }

    /**
     * 上传合同
     * @param contractTplId
     * @param doc_title
     * @param doc_url
     * @return
     */
    public Boolean uploadContract(String contractTplId,String doc_title,String doc_url) {
        FddBaseClient baseClient = new FddBaseClient(APPID, APPKEY, V, HOST);
        UploadDocsParams params = new UploadDocsParams();
        params.setContractId(contractTplId); //自定义合同id
        params.setDocTitle(doc_title); //合同标题
        //PDF文档和下载地址二选一
        //params.setFile(new File("D:\\授权协议.pdf")); //PDF文档
        params.setDocUrl(doc_url); //合同公网下载地址
        params.setDocType(".pdf"); //合同类型 目前仅支持pdf格式
        String result = baseClient.invokeUploadDocs(params);

        log.info("法大大API接口调用,上传合同返回值:{},请求参数:{}",result,JsonUtils.toJsonString(params));

        JSONObject jsonObject = JSONUtil.parseObj(result);
        if("1000".equals(jsonObject.getStr("code"))){
            //处理成功
            return true;
        }
        throw new UcodeServiceException(HrmSysResultCodeEnum.FADADA_API_REQUEST_ERROR,"合同上传",result);
    }

    /**
     * 合同模板上传
     * @param templateId
     * @param templateName
     * @param doc_url
     * @return
     */
    public Boolean UploadTemplate (String templateId,String templateName,String doc_url){
        FddBaseClient baseClient = new FddBaseClient(APPID, APPKEY, V, HOST);
        UploadTemplateParams params = new UploadTemplateParams();
        params.setTemplateId(templateId);  // 平台自定义唯一模板编号
        //下列PDF模板和文档地址二选一
        //params.setFile(new File("D:\\入职协议模板.pdf")); // PDF模板
        params.setDocUrl(doc_url); // 文档地址
        params.setTemplateName(templateName);
        String result = baseClient.invokeUploadTemplate(params);

        log.info("法大大API接口调用,上传合同模板返回值:{},请求参数:{}",result,JsonUtils.toJsonString(params));

        JSONObject jsonObject = JSONUtil.parseObj(result);
        if("1".equals(jsonObject.getStr("code"))){
            //处理成功
            return true;
        }
        throw new UcodeServiceException(HrmSysResultCodeEnum.FADADA_API_REQUEST_ERROR,"上传模板",result);
    }


    public String urlConversionByProd(String originalUrl){

        // 查找"api2/"的位置
        int index = originalUrl.indexOf("api2/");
        if (index != -1) {
            // 截取api2/后面的部分
            String suffix = originalUrl.substring(index + 5); // +5 跳过"api2/"
            // 构建新URL
            String newUrl = "https://textapi12.fadada.com/api2/" + suffix;
            log.info("法大大API接口调用,替换后的URL:{}",newUrl);
            return newUrl;
        }

        return originalUrl;
    }

    private String urlConversionByTest(String url){
        return url.replace("testapi09.fadada.com/api","realnameverify-test11.fadada.com");
    }

}
